using System;
using System.Threading.Tasks;
using System.Transactions;
using Microsoft.Extensions.Logging;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Domain;

namespace RBAC.Write.Api.Utils
{
    /// <summary>
    /// 单据审核通用助手：1=审核，0=反审核，2=退回
    /// </summary>
    public static class AuditHelper
    {
        /// <param name="repo">泛型仓储</param>
        /// <param name="id">单据主键</param>
        /// <param name="action">1=审核，0=反审核，2=退回</param>
        /// <param name="getStatus">获取当前状态</param>
        /// <param name="setStatus">设置状态</param>
        /// <param name="setAuditDate">设置审核时间（可空）</param>
        /// <param name="setAuditor">设置审核人（可空）</param>
        /// <param name="auditorName">审核人名称（审核时使用）</param>
        /// <param name="logger">可选日志</param>
        public static Task<APIResult<bool>> AuditOrReturnAsync<T>(
            IBaseRepository<T> repo,
            long id,
            int action,
            Func<T, string> getStatus,
            Action<T, string> setStatus,
            Action<T, DateTime?> setAuditDate,
            Action<T, string?> setAuditor,
            string auditorName,
            ILogger? logger = null)
            where T : BaseEntity, new()
        {
            var res = new APIResult<bool>();

            try
            {
                if (action != 0 && action != 1 && action != 2)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "无效的操作类型：仅支持 1=审核，0=反审核，2=退回";
                    return Task.FromResult(res);
                }

                var entity = repo.GetModel(id);
                if (entity == null)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "单据不存在或已被删除";
                    return Task.FromResult(res);
                }

                // 目标状态映射（可按需替换为你的真实状态值）
                string targetStatus = action switch
                {
                    1 => "审批", // 审核
                    0 => "开立", // 反审核
                    2 => "退回", // 退回
                    _ => throw new InvalidOperationException()
                };

                if (string.Equals(getStatus(entity), targetStatus, StringComparison.Ordinal))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = $"当前状态已是{targetStatus}";
                    return Task.FromResult(res);
                }

                using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);

                // 设置状态与审核信息
                setStatus(entity, targetStatus);

                if (action == 1) // 审核
                {
                    setAuditDate(entity, DateTime.Now);
                    setAuditor(entity, string.IsNullOrWhiteSpace(auditorName) ? "system" : auditorName);
                }
                else // 反审核或退回
                {
                    setAuditDate(entity, null);
                    setAuditor(entity, null);
                }

                var upd = repo.Update(entity);
                if (upd <= 0)
                    throw new InvalidOperationException("状态更新失败");

                scope.Complete();

                res.Code = APIEnums.Success;
                res.Data = true;
                res.Msg = action switch
                {
                    1 => "审核成功",
                    0 => "反审核成功",
                    2 => "退回成功",
                    _ => "成功"
                };

                logger?.LogInformation("单据[{Id}]状态更新为[{Status}]，操作类型[{Action}]", id, targetStatus, action);
            }
            catch (Exception ex)
            {
                logger?.LogError(ex, "审核处理失败：{Message}", ex.Message);
                res.Code = APIEnums.Error;
                res.Data = false;
                res.Msg = "审核处理失败";
            }

            return Task.FromResult(res);
        }
    }
}
